// 1. 如果data里面的属性是一个对象，该对象需要转换成getter和setter
// 2. 如果data的属性被重新赋值为一个对象，那么该对象也应该转换成getter 和 setter

class Observer {
    constructor(data){
        this.walk(data)
    }
    walk(data) {
        /**
         * 遍历对象的所有属性
         */
        // 1. 判断data是否是对象
        if(!data || typeof data !== 'object'){
            return
        }
        Object.keys(data).forEach(key => {
            this.defineReactive(data, key, data[key])
        })
    }
    // 调用defineproperty设置属性的getter和setter
    defineReactive(obj, key, val){
        // 如果val是对象，那么val属性也要增加getter 和 setter属性
        this.walk(val)
        const _self = this

        const dep = new Dep()
        Object.defineProperty(obj, key, {
            configurable:true,
            enumerable: true,
            get() {
                Dep.target && dep.addSub()
                return val // 为什么需要return val,如果return obj[key], obj[key]又会调用get方法，就会造成堆栈溢出的错误
            },
            set(newValue){
                if(newValue === val){  // 外部其他作用域调用get或者set方法时，set方法引用defineReactive内部的局部成员val,所有get方法和set方法形成了一个闭包
                    return
                }
                // ? set的作用是什么呢 ？ 更新当前对象的值
                val = newValue
                _self.walk(val)

                // 发布者通知订阅者
                dep.notify()
            }
        })
    }
}